//
//  UIScrollView+float.swift
//  Exchange
//
//  Created by rui on 2018/4/26.
//  Copyright © 2018年 common. All rights reserved.
//

import UIKit


class GestureScrollView: UIScrollView,UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}


class FloatModel: Hashable {
    var floatView: UIView
    var originalFrame = CGRect.zero
    var initConvertFrame = CGRect.zero
    var isFloating = false 
    
    init(float: UIView, scroll: UIScrollView) {
        floatView = float
        originalFrame = float.frame
        initConvertFrame = float.convert(float.bounds, to: scroll)
    }
    
    var hashValue: Int {
        get {
            return floatView.hashValue
        }
    }
    static func == (lhs: FloatModel, rhs: FloatModel) -> Bool {
        return lhs.floatView == rhs.floatView
    }
}


class FloatObserver: NSObject {
    
    weak var scrollView: UIScrollView?
    var floatArray: Array<FloatModel> = Array()
    init(scrollView scroll: UIScrollView) {
        scrollView = scroll
        super.init()
        scrollView?.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
    }
    
    open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        guard let scroll = object as? UIScrollView, scroll == scrollView else {
            return
        }
        var preModel: FloatModel
        var model: FloatModel
        for idx in 0..<floatArray.count {
            model = floatArray[idx]
            if idx >= 1 {
                preModel = floatArray[idx - 1]
                let preRect = preModel.floatView.convert(preModel.floatView.bounds, to: scroll)
                let curRect = model.floatView.convert(model.floatView.bounds, to: scroll)
                let gap = curRect.minY - preRect.minY
                if gap < preModel.floatView.frame.size.height {
                    preModel.floatView.bottom = model.initConvertFrame.minY
                }
            }
            if scroll.contentOffset.y >= model.initConvertFrame.origin.y {
                model.floatView.y = scroll.contentOffset.y - model.initConvertFrame.origin.y + model.originalFrame.origin.y
                model.isFloating = true
            }else {
                model.floatView.frame = model.originalFrame
                model.isFloating = false
            }
        }
    }
}

var FloatObjKey = "FloatObjKey"

extension UIScrollView {

    func add(floatView float:UIView) {
        let model = FloatModel(float: float, scroll: self)
        var floatObj: FloatObserver
        if let obj = objc_getAssociatedObject(self, &FloatObjKey) as? FloatObserver {
            floatObj = obj
        }else {
            floatObj = FloatObserver(scrollView: self)
        }
        if !floatObj.floatArray.contains(model) {
            floatObj.floatArray.append(model)
            objc_setAssociatedObject(self, &FloatObjKey, floatObj, .OBJC_ASSOCIATION_RETAIN)
        }
    }
    
    func notifiyRemoveAllFloatView() {
        guard let obj = objc_getAssociatedObject(self, &FloatObjKey) as? FloatObserver else {
            return
        }
        self.removeObserver(obj, forKeyPath: "contentOffset")
        objc_setAssociatedObject(self, &FloatObjKey, nil, .OBJC_ASSOCIATION_RETAIN)
    }
}


